#!/usr/bin/python
# -*- coding: utf-8 -*-

import Ice, IceGrid
import sys, os, thread, datetime

NORMALITY_CONCEPTS = 2

SLICE = os.path.join('..', 'slice')
FILE = os.path.join(SLICE, 'Oculus.ice')
Ice.loadSlice('--all -I/usr/share/slice', ['-I' + SLICE, FILE])

LOG_EVENT1 = 'sa_writing'
LOG_EVENT2 = 'ta_writing'
LOG_EVENT3 = 'b_processing_time'
LOG_EVENT4 = 'ena_notification'

import Oculus

class BlackboardI (Oculus.Blackboard):

    def __init__ (self, replica, comm):

        self.__replica = replica

        self.__data = {}
        self.__updates = {}
        self.__times = {}

        self.__mutex = thread.allocate_lock()

        query = IceGrid.QueryPrx.checkedCast(comm.stringToProxy("IceGrid/Query"))
        self.__sniffer = Oculus.SnifferPrx.checkedCast(query.findObjectById(comm.stringToIdentity('sniffer')))

    def read (self, id, curr = None):

        return self.__data[(id.camera, id.frame, id.obj)]

    def readSeq (self, ids, curr = None):

        values = []
        self.__mutex.acquire()

        for id in ids:
            if self.__data.has_key((id.camera, id.frame, id.obj)):
                values.append(self.__data[(id.camera, id.frame, id.obj)])

        self.__mutex.release()

        return values

    def __readFrame (self, frame_info):

        values = []

        for key in self.__data.keys():
            # TODO camera
            if key[1] == frame_info.frame:
                values.append(self.__data[key])

        return values

    def readAll (self, curr = None):

        return self.__data

    def write (self, info, curr):

        self.__mutex.acquire()

        try:
            self.__updates[(info[0].key.camera, info[0].key.frame)] += 1
        except KeyError:
            self.__updates[(info[0].key.camera, info[0].key.frame)] = 1
            self.__times[(info[0].key.camera, info[0].key.frame)] = datetime.datetime.today()

        for data in info:

            if self.__data.has_key((data.key.camera, data.key.frame, data.key.obj)):

                # Speed value.
                if data.c2 != -1.0:
                    self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT1, 0.0)
                    self.__data[(data.key.camera, data.key.frame, data.key.obj)].c2 = data.c2
                    # Trajectory value.
                else:
                    self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT2, 0.0)
                    self.__data[(data.key.camera, data.key.frame, data.key.obj)].c1 = data.c1
                    self.__data[(data.key.camera, data.key.frame, data.key.obj)].roles = data.roles
                    self.__data[(data.key.camera, data.key.frame, data.key.obj)].locations = data.locations

            else:
                # Speed value.
                if data.c2 != -1.0:
                    self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT1, 0.0)
                    # Trajectory value.
                else:
                    self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT2, 0.0)
                self.__data[(data.key.camera, data.key.frame, data.key.obj)] = data

        self.__mutex.release()

        # Notify to ENA.
        if self.__updates[(info[0].key.camera, info[0].key.frame)] == NORMALITY_CONCEPTS:
            self.__updates[(info[0].key.camera, info[0].key.frame)] = 0

            self.__times[(info[0].key.camera, info[0].key.frame)] = datetime.datetime.today() - self.__times[(info[0].key.camera, info[0].key.frame)]
            aux = str(self.__times[(info[0].key.camera, info[0].key.frame)]).split(':')
            aux2 = aux[2].split('.')
            milliseconds = float(aux2[0]) * 1000.0 + int(aux2[1]) / 1000.0
            self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT3, milliseconds)
            
            query = IceGrid.QueryPrx.checkedCast(curr.adapter.getCommunicator().stringToProxy("IceGrid/Query"))
            ena_prx = Oculus.ENAPrx.checkedCast(query.findObjectById(curr.adapter.getCommunicator().stringToIdentity('ena')))
            ena_prx = ena_prx.ice_oneway()
            # Testing.
            ena_prx = ena_prx.ice_connectionCached(False)

            self.__sniffer.notify(data.key.camera, data.key.frame, LOG_EVENT4, 0.0)
            ena_prx.notify(self.__readFrame(Oculus.TFrame(info[0].key.camera, info[0].key.frame)))
